"""
This demonstrates a minimal http upload.
This allows a user to upload up to three files at once.
It is trivial to change the number of files uploaded.

This script has security risks. A user could attempt to fill
a disk partition with endless uploads. 
If you have a system open to the public you would obviously want
to limit the size and number of files written to the disk.
"""

import os, sys, hashlib
from time import time
from flask import Flask, request, url_for, abort, send_file, safe_join
from werkzeug import secure_filename
from writeHtmlTemplate import writeHtmlTemplate

app = Flask(__name__)


DOWNLOAD_DIR = '..\\files'


@app.route('/')
def writeUploadPage(msg=""):
	#content = '''
#After you choose a file and click "upload", you will be given a link to download the file.  Send this link through email, text or IM.  Anyone who has the link can download the file for 30 days.
	#'''
	content = '<form enctype="multipart/form-data" action="/upload" method="POST">'
	content += '<h2>Step 1: Choose File</h2><input name="file" type="file" size=60>'
	content += '<br>'
	content += '<h2>Step 2: Click Upload</h2><input value="Upload" type="submit" size=60>'
	content += '</form>'
	content += '<br>'
	content += 'And then.........<br>'
	content += msg
	
	return writeHtmlTemplate("", content)


@app.route('/download/')
@app.route('/download/<path:dirname>/<path:filename>')
def download(dirname, filename):
	
	if '..' in dirname  or dirname.startswith('/'):
		abort(404)
	if '..' in filename or filename.startswith('/'):
		abort(404)
	
	# Just in case
	filename = secure_filename(filename)
	dirname  = secure_filename(dirname)

	path = safe_join(DOWNLOAD_DIR, dirname)
	path = safe_join(path, filename)
	path = os.path.abspath(path)

	if os.path.isfile(path):
		return send_file(path)
	else:
		abort(404)




@app.route('/upload', methods=['GET', 'POST'])
def upload():
	"""
	This saves a file uploaded by an HTML form.
   	The form_field is the name of the file input field from the form.
   	For example, the following form_field would be "file_1":
	   <input name="file_1" type="file">
   	The DOWNLOAD_DIR is the directory where the file will be written.
   	If no file was uploaded or if the field does not exist then
   	this does nothing.
	"""

	try: # Windows needs stdio set for binary mode.
		import msvcrt
		msvcrt.setmode (0, os.O_BINARY) # stdin  = 0
		msvcrt.setmode (1, os.O_BINARY) # stdout = 1
	except ImportError:
		pass

	debug_msg = ''

	if request.method == 'POST':
		f = request.files['file']

		# Construct a path using unix time
		unixtime = str(int(time()))
		s_filename = secure_filename(f.filename)
		save_path = os.path.join(DOWNLOAD_DIR, unixtime, s_filename)

		# Create the directory
		dirname = os.path.dirname(save_path)
		if not os.path.exists(dirname): os.makedirs(dirname)

		try:
			f.save(save_path)
			f.close()
		except:
			return writeHtmlTemplate('Upload Failed', '')

		#debug_msg = 'filename: ' + filename + '\n'

		download_path = unixtime + '/' + s_filename
		file_url = url_for('download', _external=True) + download_path

		content = '<A HREF="' + file_url + '"><h3>' + file_url + '</A></h3>'
	else:
		return writeHtmlTemplate('Failed', '')

	if debug_msg:
		content += '<pre>' + debug_msg + '</pre>'

	return writeHtmlTemplate('Step 3: <b>copy the link</b> and send it to a friend<br>', content)


def get_md5(filename):
	import hashlib

	md5 = hashlib.md5()

	with open(filename,'rb') as f: 
		for chunk in iter(lambda: f.read(8192), ''): 
			md5.update(chunk)

	return md5.hexdigest()


if __name__ == '__main__':
	app.debug = True
	app.run()




